package com.bcx.wind.workflow.imp;

import com.bcx.wind.workflow.WindEngine;
import com.bcx.wind.workflow.core.constant.WindDB;
import com.bcx.wind.workflow.core.lock.Lock;
import com.bcx.wind.workflow.imp.service.*;
import com.bcx.wind.workflow.interceptor.AfterInterceptor;
import com.bcx.wind.workflow.interceptor.CustomInterceptor;
import org.apache.ibatis.session.SqlSessionFactory;

import javax.sql.DataSource;

/**
 * 工作流引擎建造者
 *
 * @author zhanglei
 */
public class WindEngineBuilder {

    /**
     * 数据源
     */
    private DataSource dataSource;

    /**
     * 持久层类型
     */
    private WindDB db;

    /**
     * mybatis sqlSessionFactory
     */
    private SqlSessionFactory sqlSessionFactory;

    /**
     * 后置拦截器
     */
    private AfterInterceptor afterInterceptor;


    /**
     * 工作流自定义拦截器
     */
    private CustomInterceptor customInterceptor;

    /**
     * 工作流使用的锁
     */
    private Lock lock;

    private static class LoaderInstance{
        private static final WindEngineBuilder BUILDER = new WindEngineBuilder();
    }

    private WindEngineBuilder(){}

    public static WindEngineBuilder getInstance(){
        return LoaderInstance.BUILDER;
    }

    public WindEngineBuilder buildSqlSessionFactory(SqlSessionFactory sqlSessionFactory){
        this.sqlSessionFactory = sqlSessionFactory;
        return this;
    }

    public WindEngineBuilder buildAfterInterceptor(AfterInterceptor interceptor){
        this.afterInterceptor = interceptor;
        return this;
    }

    public WindEngineBuilder  buildCustomInterceptor(CustomInterceptor customInterceptor){
        this.customInterceptor = customInterceptor;
        return this;
    }

    public void setLock(Lock lock) {
        this.lock = lock;
    }

    public WindEngineBuilder buildDataSource(DataSource dataSource){
        this.dataSource = dataSource;
        return this;
    }

    public WindEngineBuilder buildDbType(WindDB db){
        this.db = db;
        return this;
    }

    public WindEngine buildEngine(){
        Configuration configuration = buildConfiguration();
        //构建拦截器
        configuration.buildCommandExecutor();
        //后置拦截器
        configuration.setAfterInterceptor(this.afterInterceptor);
        configuration.setCustomInterceptor(this.customInterceptor);
        if(this.lock != null){
            configuration.setLock(this.lock);
        }
        //构建工作流各个服务
        buildService(configuration);
        //构建引擎
        WindEngine engine = new WindEngineImpl(configuration);
        configuration.setWindEngine(engine);
        return engine;
    }

    private Configuration  buildConfiguration(){
        Configuration configuration = new Configuration(this.dataSource,this.db);
        configuration.setSqlSessionFactory(sqlSessionFactory);
        configuration.buildAccess();
        return configuration;
    }

    private void buildService(Configuration configuration){
        RuntimeService runtimeService = new RuntimeServiceImpl();
        RepositoryService repositoryService = new RepositoryServiceImpl();
        ManagerService managerService = new ManagerServiceImpl();
        HistoryService historyService = new HistoryServiceImpl();
        WindCoreService windCoreService = new WindCoreServiceImpl();

        configuration.setRuntimeService(runtimeService);
        configuration.setRepositoryService(repositoryService);
        configuration.setHistoryService(historyService);
        configuration.setManagerService(managerService);
        configuration.setWindCoreService(windCoreService);
        configuration.initServiceConfig();
    }


}
